home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / binutils.7 / binutils / binutils-2.7 / gprof / source.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-04  |  4.1 KB  |  224 lines

  1. /*
  2.  * Keeps track of source files.
  3.  */
  4. #include "gprof.h"
  5. #include "libiberty.h"
  6. #include "search_list.h"
  7. #include "source.h"
  8.  
  9. #define EXT_ANNO "-ann"        /* postfix of annotated files */
  10.  
  11. /*
  12.  * Default option values:
  13.  */
  14. bool create_annotation_files = FALSE;
  15.  
  16. Search_List src_search_list =
  17. {0, 0};
  18. Source_File *first_src_file = 0;
  19.  
  20.  
  21. Source_File *
  22. DEFUN (source_file_lookup_path, (path), const char *path)
  23. {
  24.   Source_File *sf;
  25.  
  26.   for (sf = first_src_file; sf; sf = sf->next)
  27.     {
  28.       if (strcmp (path, sf->name) == 0)
  29.     {
  30.       break;
  31.     }
  32.     }
  33.   if (!sf)
  34.     {
  35.       /* create a new source file descriptor: */
  36.  
  37.       sf = (Source_File *) xmalloc (sizeof (*sf));
  38.       memset (sf, 0, sizeof (*sf));
  39.       sf->name = xstrdup (path);
  40.       sf->next = first_src_file;
  41.       first_src_file = sf;
  42.     }
  43.   return sf;
  44. }
  45.  
  46.  
  47. Source_File *
  48. DEFUN (source_file_lookup_name, (filename), const char *filename)
  49. {
  50.   const char *fname;
  51.   Source_File *sf;
  52.   /*
  53.    * The user cannot know exactly how a filename will be stored in
  54.    * the debugging info (e.g., ../include/foo.h
  55.    * vs. /usr/include/foo.h).  So we simply compare the filename
  56.    * component of a path only:
  57.    */
  58.   for (sf = first_src_file; sf; sf = sf->next)
  59.     {
  60.       fname = strrchr (sf->name, '/');
  61.       if (fname)
  62.     {
  63.       ++fname;
  64.     }
  65.       else
  66.     {
  67.       fname = sf->name;
  68.     }
  69.       if (strcmp (filename, fname) == 0)
  70.     {
  71.       break;
  72.     }
  73.     }
  74.   return sf;
  75. }
  76.  
  77.  
  78. FILE *
  79. DEFUN (annotate_source, (sf, max_width, annote, arg),
  80.        Source_File * sf AND int max_width
  81.        AND void (*annote) PARAMS ((char *buf, int w, int l, void *arg))
  82.        AND void *arg)
  83. {
  84.   static bool first_file = TRUE;
  85.   int i, line_num, nread;
  86.   bool new_line;
  87.   char buf[8192];
  88.   char fname[PATH_MAX];
  89.   char *annotation, *name_only;
  90.   FILE *ifp, *ofp;
  91.   Search_List_Elem *sle = src_search_list.head;
  92.  
  93.   /*
  94.    * Open input file.  If open fails, walk along search-list until
  95.    * open succeeds or reaching end of list:
  96.    */
  97.   strcpy (fname, sf->name);
  98.   if (sf->name[0] == '/')
  99.     {
  100.       sle = 0;            /* don't use search list for absolute paths */
  101.     }
  102.   name_only = 0;
  103.   while (TRUE)
  104.     {
  105.       DBG (SRCDEBUG, printf ("[annotate_source]: looking for %s, trying %s\n",
  106.                  sf->name, fname));
  107.       ifp = fopen (fname, FOPEN_RB);
  108.       if (ifp)
  109.     {
  110.       break;
  111.     }
  112.       if (!sle && !name_only)
  113.     {
  114.       name_only = strrchr (sf->name, '/');
  115.       if (name_only)
  116.         {
  117.           /* try search-list again, but this time with name only: */
  118.           ++name_only;
  119.           sle = src_search_list.head;
  120.         }
  121.     }
  122.       if (sle)
  123.     {
  124.       strcpy (fname, sle->path);
  125.       strcat (fname, "/");
  126.       if (name_only)
  127.         {
  128.           strcat (fname, name_only);
  129.         }
  130.       else
  131.         {
  132.           strcat (fname, sf->name);
  133.         }
  134.       sle = sle->next;
  135.     }
  136.       else
  137.     {
  138.       if (errno == ENOENT)
  139.         {
  140.           fprintf (stderr, "%s: could not locate `%s'\n",
  141.                whoami, sf->name);
  142.         }
  143.       else
  144.         {
  145.           perror (sf->name);
  146.         }
  147.       return 0;
  148.     }
  149.     }
  150.  
  151.   ofp = stdout;
  152.   if (create_annotation_files)
  153.     {
  154.       /* try to create annotated source file: */
  155.       const char *filename;
  156.  
  157.       /* create annotation files in the current working directory: */
  158.       filename = strrchr (sf->name, '/');
  159.       if (filename)
  160.     {
  161.       ++filename;
  162.     }
  163.       else
  164.     {
  165.       filename = sf->name;
  166.     }
  167.  
  168.       strcpy (fname, filename);
  169.       strcat (fname, EXT_ANNO);
  170.       ofp = fopen (fname, "w");
  171.       if (!ofp)
  172.     {
  173.       perror (fname);
  174.       return 0;
  175.     }
  176.     }
  177.  
  178.   /*
  179.    * Print file names if output goes to stdout and there are
  180.    * more than one source file:
  181.    */
  182.   if (ofp == stdout)
  183.     {
  184.       if (first_file)
  185.     {
  186.       first_file = FALSE;
  187.     }
  188.       else
  189.     {
  190.       fputc ('\n', ofp);
  191.     }
  192.       if (first_output)
  193.     {
  194.       first_output = FALSE;
  195.     }
  196.       else
  197.     {
  198.       fprintf (ofp, "\f\n");
  199.     }
  200.       fprintf (ofp, "*** File %s:\n", sf->name);
  201.     }
  202.  
  203.   annotation = xmalloc (max_width + 1);
  204.   line_num = 1;
  205.   new_line = TRUE;
  206.   while ((nread = fread (buf, 1, sizeof (buf), ifp)) > 0)
  207.     {
  208.       for (i = 0; i < nread; ++i)
  209.     {
  210.       if (new_line)
  211.         {
  212.           (*annote) (annotation, max_width, line_num, arg);
  213.           fputs (annotation, ofp);
  214.           ++line_num;
  215.           new_line = FALSE;
  216.         }
  217.       new_line = (buf[i] == '\n');
  218.       fputc (buf[i], ofp);
  219.     }
  220.     }
  221.   free (annotation);
  222.   return ofp;
  223. }
  224.